﻿using System;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using Elsa.Services.Models;
using HengTong.Model;
using HengTong.Model._Admin;
using HengTong.Model.Db.Hr;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.WorkFlow;

namespace HengTong.ViewModel.Hr.SysHrRetireRequestBillVms;

public partial class SysHrRetireRequestBillVm
{
    [WorkflowOperation("驳回", "将单据状态设置为草稿", "退休申请")]
    public async Task Reject(ActivityExecutionContext context)
    {
        Entity.BillStatus = BillStatus.草稿;
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        DC.UpdateProperty(Entity, x => x.BillStatus);
        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("取消", "将流程状态设置为取消", "退休申请")]
    public async Task Cancel(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已取消;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("完成", "将流程状态设置为已完成", "退休申请")]
    public async Task Complete(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已完成;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("退休处理", "更新人员档案状态为退休并停用账号", "退休申请")]
    public async Task ProcessRetirement(ActivityExecutionContext context)
    {
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
        {
            currentUser = input.CurrentUser?.ITCode ?? "workflow";
        }

        var scope = Wtm.ServiceProvider.CreateScope();
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<SysHrRetireRequestBillVm>>();

        using var transactionScope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
                Timeout = TimeSpan.FromMinutes(10)
            },
            TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            logger.LogInformation("开始处理退休申请，单据ID: {EntityId}, 工号: {StaffNo}, 操作人: {CurrentUser}, 时间: {Time}",
                Entity.ID, Entity.StaffNo, currentUser, DateTime.Now);

            // 更新人员档案状态为退休
            await DC.Set<SysPerson>()
                .Where(p => p.ID == Entity.PersonId)
                .ExecuteUpdateAsync(u => u
                    .SetProperty(x => x.State, PersonState.退休)
                    .SetProperty(x => x.UpdateTime, DateTime.Now)
                    .SetProperty(x => x.UpdateBy, currentUser)
                );

            // 停用账号
            await DC.Set<FrameworkUser>()
                .Where(u => u.ITCode == Entity.StaffNo)
                .ExecuteUpdateAsync(u => u
                    .SetProperty(x => x.IsValid, false)
                    .SetProperty(x => x.UpdateTime, DateTime.Now)
                    .SetProperty(x => x.UpdateBy, currentUser)
                );

            // 更新单据状态
            if (Entity is IBasePoco poco)
            {
                poco.UpdateTime = DateTime.Now;
                DC.UpdateProperty(Entity, x => x.UpdateTime);
                poco.UpdateBy = currentUser;
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }

            if (Entity is IBill bill)
            {
                bill.WorkflowStatus = WorkflowStatus.已完成;
                DC.UpdateProperty(Entity, x => x.WorkflowStatus);
            }

            await DC.SaveChangesAsync();

            // 清除用户缓存
            await Wtm.RemoveUserCache(Entity.StaffNo);

            transactionScope.Complete();

            logger.LogInformation("成功处理退休申请，工号: {StaffNo}, 流程状态: {WorkflowStatus}",
                Entity.StaffNo, Entity.WorkflowStatus);
        }
        catch (Exception e)
        {
            logger.LogError(e, "处理退休申请失败，单据ID: {EntityId}, 工号: {StaffNo}, 操作人: {CurrentUser}, 时间: {Time}",
                Entity.ID, Entity.StaffNo, currentUser, DateTime.Now);

            MSD.AddModelError(" ", $"处理退休申请失败: {e.Message}");
        }
    }
}